﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 线程的暂停_继续_取消
{
    public partial class Form1 : Form
    {
        // 通知 CancellationToken,告知其应被取消
        private CancellationTokenSource cancellationToken = new CancellationTokenSource();

        // 初始化为true时执行WaitOne不阻塞(使用它可以终止或继续线程)
        private ManualResetEvent manual = new ManualResetEvent(true);

        public Form1()
        {
            InitializeComponent();

            Task.Run(async () =>
            {
                for (int i = 0; i < 100; i++)
                {
                    // 判断线程是否已取消
                    if (cancellationToken.IsCancellationRequested) return;

                    manual.WaitOne();

                    this.Invoke(new Action(() =>
                    {
                        textBox1.Text += i + " ";
                    }));

                    await Task.Delay(1000);
                }
            }, cancellationToken.Token);

        }

        /// <summary>
        /// 窗体加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            // 通知取消Token,线程取消时提示
            cancellationToken.Token.Register(() => { MessageBox.Show("任务已取消"); });
        }

        /// <summary>
        /// 暂停
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPause_Click(object sender, EventArgs e)
        {
            // 阻塞线程(暂停线程)
            manual.Reset();
        }

        /// <summary>
        /// 继续
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnContinue_Click(object sender, EventArgs e)
        {
            // 不阻塞线程(继续线程)和ManualResetEvent manual = new ManualResetEvent(true)一样不阻塞线程
            manual.Set();
        }

        /// <summary>
        /// 取消线程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            // 取消线程
            // cancellationToken.Cancel();
            // 过几秒之后取消线程,这里1秒后取消
            cancellationToken.CancelAfter(1000);
        }
    }
}
